/*
    Copyright (C) 2010-2011 mdis
    
    This file is part of mdis.
    Written by Laügt Franz <znarf94@yahoo.fr>

    mdis is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    mdis is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with mdis.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "global.h"

int open_hex(infile_t * hexfile)
{
	uint8_t * hexptr;	//pointe dans filebuf
	uint8_t * binptr;	//pointe dans binbuf
	uint8_t * filebuf;
	unsigned char i;
	unsigned char nbytes;	//nb d'octets de la ligne courante
	uint8_t checksum = 0;
	unsigned char line=0;

	hexfile->nbytes_tot = 0;	//compteur du nb d'octets total à convertir

	hexfile->file = fopen(hexfile->fname,"r");	//ouverture du fichier si il n'est pas déja ouvert
	if(hexfile->file == NULL)
		return 1;

	fseek(hexfile->file, 0, SEEK_END);
	hexfile->fsize = ftell(hexfile->file);	//mesure de la taille du fichier d'entrée
	fseek(hexfile->file, 0, SEEK_SET);

	filebuf = calloc(hexfile->fsize,sizeof(char));		//allocation d'un buffer de la même taille
	fread(filebuf, sizeof(char), hexfile->fsize, hexfile->file);	//copie du fichier dans ce buffer

	fclose(hexfile->file);		//fermeture du fichier

	hexptr = filebuf;	//initialisation du pointeur sur ce buffer

	while(*hexptr != 0)	//boucle pour mesurer la taille nécéssaire pour binbuf
	{
		if(*hexptr == ':')
		{
			if(str2byte(hexptr+7) == 0x00)
			{
				hexfile->nbytes_tot += str2byte(hexptr+1) + 3;
			}
		}
		hexptr++;
	}

	if(hexfile->nbytes_tot == 0)
		return 2;

	hexfile->binbuf = calloc(hexfile->nbytes_tot, sizeof(char));	//allocation de mem pour stocker le résultat binaire
	
	binptr = hexfile->binbuf;	//réinitialisation des pointeurs sur binbuf et filebuf
	hexptr = filebuf;
	
	while(*hexptr != 0)
	{
		if(*hexptr == ':')
		{
			if(str2byte(hexptr+7) == 0x00)
			{
				hexptr++;	//pour sauter le ':'
				nbytes = str2byte(hexptr);
				*binptr = nbytes;
				*(binptr+1) = str2byte(hexptr+2);
				*(binptr+2) = str2byte(hexptr+4);
				binptr+=3;
				hexptr+=8;
				//printf("nbytes = %d\n",nbytes);
				checksum = 0;
				for(i=0;i<nbytes;i++)
				{
					*binptr = str2byte(hexptr);
					checksum += *binptr;
					binptr++;
					hexptr+=2;
				}
				line++;
				/*if(str2byte(hexptr) != ~checksum)
				{
					//printf("/!\\ Bad checksum on line %hd\n",line);
					return 3;
				}*/
				hexptr+=2;
			} else break;
		} else { hexptr++; }
	}
	
	free(filebuf);

	return 0;
}

uint16_t
 get_nbytes_hex ( infile_t * hex )
{
	uint16_t i = 0, n = 0;
	while ( i<hex->nbytes_tot )
	{
		n = n + hex->binbuf[i];
		i = i + hex->binbuf[i] + 3;
	}
	return n;
}

void
 close_hex ( infile_t * hex )
{
	if ( hex->binbuf != NULL )
		free ( hex->binbuf );
}

